// 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图，计算按此排列的柱子，下雨之后能接多少雨水。

//  输入：height = [0,1,0,2,1,0,1,3,2,1,2,1]
// 输出：6
// 解释：上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图，在这种情况下，可以接 6 个单位的雨水（蓝色部分表示雨水）。 

//解法一：动态规划+双指针
class Solution{
    public int trap(int[] height)
    {
        int sum = 0;
        int max_right = 0;
        int max_left = 0;
        int left = 1;
        int right = height.length - 2;
        for(int i=1;i<height.length-1;i++)
        {
            if(height[left-1]<height[right+1])
            {
                max_left = Math.max(max_left,height[left-1]);
                if(max_left>height[left]){
                    sum = sum + (max_left-height[left]);
                }
                left++;
            }
            else{
                max_right = Math.max(max_right,height[right+1]);
                if(max_right>height[right])
                {
                    sum = sum + (max_right-height[right]);
                }
                right--;
            }
        }
        return sum;
    }
}
//解法二：栈
public int trap6(int[] height) {
    int sum = 0;
    Stack<Integer> stack = new Stack<>();
    int current = 0;
    while (current < height.length) {
        //如果栈不空并且当前指向的高度大于栈顶高度就一直循环
        while (!stack.empty() && height[current] > height[stack.peek()]) {
            int h = height[stack.peek()]; //取出要出栈的元素
            stack.pop(); //出栈
            if (stack.empty()) { // 栈空就出去
                break; 
            }
            int distance = current - stack.peek() - 1; //两堵墙之前的距离。
            int min = Math.min(height[stack.peek()], height[current]);
            sum = sum + distance * (min - h);
        }
        stack.push(current); //当前指向的墙入栈
        current++; //指针后移
    }
    return sum;
}
